home *** CD-ROM | disk | FTP | other *** search
- /*
- * Command-line program for hiding and extracting messages within
- * the whitespace of text files.
- *
- * Usage: snow [-C][-Q][-S][-p passwd][-l line-len] [-f file | -m message]
- * [infile [outfile]]
- *
- * -C : Use compression
- * -Q : Be quiet
- * -S : Calculate the space available in the file
- * -l : Maximum line length allowanble
- * -p : Specify the password to encrypt the message
- *
- * -f : Insert the message contained in the file
- * -m : Insert the message given
- *
- * If the program is executed without either of the -f or -m options
- * then the program will attempt to extract a concealed message.
- * The output will go to outfile if specified, stdout otherwise.
- *
- * Written by Matthew Kwan - December 1996
- */
-
- #include "snow.h"
-
-
- /*
- * Declaration of global variables.
- */
-
- BOOL compress_flag = FALSE;
- BOOL quiet_flag = FALSE;
- int line_length = 80;
-
-
- /*
- * Encode a single character.
- */
-
- static BOOL
- character_encode (
- unsigned char c,
- FILE *infile,
- FILE *outfile
- ) {
- int i;
-
- for (i=0; i<8; i++) {
- int bit = ((c & (128 >> i)) != 0) ? 1 : 0;
-
- if (!compress_bit (bit, infile, outfile))
- return (FALSE);
- }
-
- return (TRUE);
- }
-
-
- /*
- * Encode a string of characters.
- */
-
- static BOOL
- message_string_encode (
- const char *msg,
- FILE *infile,
- FILE *outfile
- ) {
- compress_init ();
-
- while (*msg != '\0') {
- if (!character_encode (*msg, infile, outfile))
- return (FALSE);
- msg++;
- }
-
- return (compress_flush (infile, outfile));
- }
-
-
- /*
- * Encode the contents of a file.
- */
-
- static BOOL
- message_fp_encode (
- FILE *msg_fp,
- FILE *infile,
- FILE *outfile
- ) {
- int c;
-
- compress_init ();
-
- while ((c = fgetc (msg_fp)) != EOF)
- if (!character_encode (c, infile, outfile))
- return (FALSE);
-
- if (ferror (msg_fp) != 0) {
- perror ("Message file");
- return (FALSE);
- }
-
- return (compress_flush (infile, outfile));
- }
-
-
- /*
- * Program's starting point.
- * Processes command-line args and starts things running.
- */
-
- void
- main (
- int argc,
- char *argv[]
- ) {
- int c;
- int optind;
- BOOL errflag = FALSE;
- BOOL space_flag = FALSE;
- char *passwd = NULL;
- char *message_string = NULL;
- FILE *message_fp = NULL;
- FILE *infile = stdin;
- FILE *outfile = stdout;
-
- optind = 1;
- for (optind = 1; optind < argc
- #ifdef unix
- && argv[optind][0] == '-';
- #else
- && (argv[optind][0] == '-' || argv[optind][0] == '/');
- #endif
- optind++) {
- char c = argv[optind][1];
- char *optarg;
-
- switch (c) {
- case 'C':
- compress_flag = TRUE;
- break;
- case 'Q':
- quiet_flag = TRUE;
- break;
- case 'S':
- space_flag = TRUE;
- break;
- case 'f':
- if (argv[optind][2] != '\0')
- optarg = &argv[optind][2];
- else if (++optind == argc) {
- errflag = TRUE;
- break;
- } else
- optarg = argv[optind];
-
- if ((message_fp = fopen (optarg, "r")) == NULL) {
- perror (optarg);
- errflag = TRUE;
- }
- break;
- case 'l':
- if (argv[optind][2] != '\0')
- optarg = &argv[optind][2];
- else if (++optind == argc) {
- errflag = TRUE;
- break;
- } else
- optarg = argv[optind];
-
- if (sscanf (optarg, "%d", &line_length) != 1
- || line_length < 8) {
- fprintf (stderr, "Illegal line length value '%s'\n",
- optarg);
- errflag = TRUE;
- }
- break;
- case 'm':
- if (argv[optind][2] != '\0')
- optarg = &argv[optind][2];
- else if (++optind == argc) {
- errflag = TRUE;
- break;
- } else
- optarg = argv[optind];
-
- message_string = optarg;
- break;
- case 'p':
- if (argv[optind][2] != '\0')
- optarg = &argv[optind][2];
- else if (++optind == argc) {
- errflag = TRUE;
- break;
- } else
- optarg = argv[optind];
-
- passwd = optarg;
- break;
- default:
- fprintf (stderr, "Illegal option '%s'\n", argv[optind]);
- errflag = TRUE;
- break;
- }
-
- if (errflag)
- break;
- }
-
- if (message_string != NULL && message_fp != NULL) {
- fprintf (stderr, "Cannot specify both message string and file\n");
- errflag = TRUE;
- }
-
- if (errflag || optind < argc - 2) {
- fprintf (stderr, "Usage: %s [-C][-Q][-S]", argv[0]);
- fprintf (stderr, "[-p passwd][-l line-len]");
- fprintf (stderr, " [-f file | -m message]\n");
- fprintf (stderr, "\t\t\t\t\t[infile [outfile]]\n");
- exit (1);
- }
-
- if (passwd != NULL)
- password_set (passwd);
-
- if (optind < argc) {
- if ((infile = fopen (argv[optind], "r")) == NULL) {
- perror (argv[optind]);
- exit (1);
- }
- }
-
- if (optind + 1 < argc) {
- if ((outfile = fopen (argv[optind + 1], "w")) == NULL) {
- perror (argv[optind + 1]);
- exit (1);
- }
- }
-
- if (space_flag) {
- space_calculate (infile);
- } else if (message_string != NULL) {
- if (!message_string_encode (message_string, infile, outfile))
- exit (1);
- } else if (message_fp != NULL) {
- if (!message_fp_encode (message_fp, infile, outfile))
- exit (1);
- fclose (message_fp);
- } else {
- if (!message_extract (infile, outfile))
- exit (1);
- }
-
- if (outfile != stdout)
- fclose (outfile);
- if (infile != stdout)
- fclose (infile);
-
- exit (0);
- }
-